﻿using UnityEngine;
using System.Collections;
using Dict.DataModel;
using System.Text;
namespace Room
{
    public class RCLODPlayer : RCLODBase
    {
        public RCLODPlayer(RoomCharactor owner)
            : base(owner)
        {
            type = LODType.Player;
        }

        public string heroId;
        protected string weaponId;

        protected string modelName = "";
        protected float modelScale = 1f;
        protected float modelHeight = 0f;

        protected bool running=false;     //运行中
        protected bool inView = false;    //视野内


        protected bool weaponLoaded = false;
        protected bool weaponLoadCompleted = false;

        public void Init(string heroId, string weaponId,float scale=0f)
        {
            SetHero(heroId);
            if (scale > 0f)
            {
                this.modelScale = scale;
            }
            this.weaponId = weaponId;
            weaponLoaded = false;
            weaponLoadCompleted = false;

        }




        public override void DoStart()
        {
            ShowShadow();
            PlayAnim("stand",WrapMode.Loop);
            //SetMeshFrameAnimate(true);
            //Debug.Log("RCLODPlayer DoStart: " + owner.name);
        }

        public override void DoStop()
        {
            UnloadWeapon();
            UnloadModel();
            //Debug.Log("RCLODPlayer DoStop: " + owner.name);
        }

        public override void DoResume()
        {
            base.DoResume();
            running = true;

            RefreshModel();
        }

        public override void DoPause()
        {
            base.DoPause();
            running = false;

            RefreshModel();
        }
        public static bool usingLod = true;
        protected virtual void SetHero(string heroId)
        {
            this.heroId = heroId;
            TableHero dataHero = Dict.Blo.DictHeroBlo.GetTableHero(heroId);
            if (GetLevel() >= (int)LODLevel.High || !usingLod)
            {
                this.modelName = dataHero.resName;
            }
            else
            {
#if UNITY_EDITOR && !TESTASSET
                string[] assetPaths = UnityEditor.AssetDatabase.GetAssetPathsFromAssetBundleAndAssetName("model/" + dataHero.resName + "_low", dataHero.resName + "_low");
                if (assetPaths.Length != 0)
#else
                if (AssetLoad.AssetBundleManager.Instance.IsAssetExist("model/" + dataHero.resName + "_low"))
#endif
                {

                    this.modelName = dataHero.resName + "_low";
                }
                else
                {
                    this.modelName = dataHero.resName;
                }
            }

            this.modelHeight = (float)dataHero.Height;
            this.modelScale = (float)dataHero.ScaleFactor;
        }
        public override float GetHeight()
        {
            return modelHeight;
        }
         
        public void Refresh(string newHeroId,string newWeaponId)
        {
            if (string.IsNullOrEmpty(newHeroId) ) {
                Debug.LogError("[RCLODPlayer] Args error. NewHeroId:" + newHeroId );
                return;
            }

            if (!newHeroId.Equals(heroId))
            {
                SetHero(newHeroId);
                this.weaponId = newWeaponId;
                UnloadModel();

                this.weaponId = newWeaponId;
                weaponLoaded = false;
                weaponLoadCompleted = false;
                RefreshModel();
            }
            else {
                if (!newWeaponId.Equals(weaponId)) {
                    this.weaponId = newWeaponId;
                    weaponLoaded = false;
                    weaponLoadCompleted = false;
                    RefreshModel();
                }
            }
        }
        public override void SetLevel(int lodLevel)
        {
            if(GetLevel()!=lodLevel)
            {
                base.SetLevel(lodLevel);
                UnloadModel();
                SetHero(heroId);
                RefreshModel();
            }
            
        }
        public override void SetInView(bool inView)
        {
            base.SetInView(inView);
            this.inView = inView;
            RefreshModel();
        }
        public override bool GetInView()
        {
            return inView;
        }

        private void RefreshModel()
        {
            if(running&&level>0&&inView)
            {
                if(!isMeshFrameAnimating||!weaponLoadCompleted)
                {
                    if (model == null)
                    {
                        LoadModel(modelName);
                        return;
                    }
                    if (!model.activeSelf)
                    {
                        model.SetActive(true);
                        ResumeAnim();
                    }
                    if (!weaponLoaded)
                    {
                        LoadWeapon();
                    }
                    if(meshModel != null)
                    {
                        meshModel.SetActive(false);
                    }
                }
                else
                {

                    if (meshModel == null)
                    {
                        CreateModelMesh();
                    }
                    if(!meshModel.activeSelf)
                    {
                        meshModel.SetActive(true);
                        ResumeAnim();
                    }
                    if(model!=null)
                    {
                        model.SetActive(false);
                    }
                }
            }
            else
            {
                if(model!=null)
                {
                    model.SetActive(false);
                }
                if(meshModel != null)
                {
                    meshModel.SetActive(false);
                }
            }
            
        }


        protected override void OnLoadModelComplete()
        {
            model.GetComponent<ModelRenderKit>().SetModelScale(modelScale);
            CommonMethod.ChangeLayer(model.transform, LayerName.SceneActor);
            RefreshModel();
        }

        protected virtual void LoadWeapon() {
            if (model != null)
            {
                weaponLoaded = true;
                weaponLoadCompleted = false;
                if (weaponId==null)
                {
                    weaponId = "";
                }
                //if(RenderManager.Quality!=RenderLevel.Low)
                    owner.StartCoroutine(_LoadWeapon());
            }
        }
        private IEnumerator _LoadWeapon()
        {
            yield return model.GetComponent<ModelRenderKit>().LoadWeapons(heroId, weaponId);
            weaponLoadCompleted = true;
            if (meshModel!=null)
            {
                CreateMeshWeapon();
            }
        }
        protected virtual void UnloadWeapon()
        {
            if (model != null)
            {
                model.GetComponent<ModelRenderKit>().UnloadWeapons();
            }
        }


#region MeshAnimation
        //状态 播放骨骼动画并保存 或 播放帧动画
        private GameObject meshModel = null;
        private GameObject meshLeftWeapon = null;
        private GameObject meshRightWeapon = null;
        private MeshFrameAnimation meshFrameAnimation;
        private bool isMeshFrameAnimating = false;//蒙皮模型还是帧动画模型

        public override void PlayAnim(string animName, WrapMode wrapMode)
        {
            if(isMeshFrameAnimating&& meshFrameAnimation!=null)
            {
                meshFrameAnimation.Play(animName);
            }
            else
            {
                base.PlayAnim(animName, wrapMode);
            }
        }
        public override void ResumeAnim()
        {
            if (isMeshFrameAnimating && meshFrameAnimation != null)
            {
                if(!string.IsNullOrEmpty(animName) )
                {
                    meshFrameAnimation.Play(animName);
                }
            }
            else
            {
                base.ResumeAnim();
            }
        }

        public void SetMeshFrameAnimate(bool meshFrameAniate)
        {
            isMeshFrameAnimating = meshFrameAniate;
            RefreshModel();
        }
        private void CreateModelMesh()
        {
            meshModel = new GameObject(modelName + "_mesh");
            meshModel.transform.SetParent(owner.transform);
            meshModel.transform.localPosition = Vector3.zero;
            meshModel.transform.localEulerAngles = new Vector3(-90, 0, 0);
            meshModel.transform.localScale = Vector3.one;
            CommonMethod.ChangeLayer(meshModel.transform, LayerName.SceneActor);

            var meshFilter = meshModel.AddComponent<MeshFilter>();
            var meshRenderer = meshModel.AddComponent<MeshRenderer>();
            meshRenderer.materials = modelRenderKit.skinnedMeshRenderer.materials;

            meshLeftWeapon = new GameObject("leftWeapon");
            meshRightWeapon = new GameObject("rightWeapon");

            meshLeftWeapon.transform.SetParent(meshModel.transform);
            meshLeftWeapon.transform.localPosition = Vector3.zero;
            meshLeftWeapon.transform.localEulerAngles = Vector3.zero;
            meshLeftWeapon.transform.localScale = Vector3.one;
            meshRightWeapon.transform.SetParent(meshModel.transform);
            meshRightWeapon.transform.localPosition = Vector3.zero;
            meshRightWeapon.transform.localEulerAngles = Vector3.zero;
            meshRightWeapon.transform.localScale = Vector3.one;

            meshFrameAnimation = meshModel.AddComponent<MeshFrameAnimation>();
            meshFrameAnimation.Init(model, meshFilter, modelName, meshLeftWeapon.transform, meshRightWeapon.transform);

            if(weaponLoadCompleted)
            {
                CreateMeshWeapon();
            }
        }

        private void CreateMeshWeapon()
        {
            if(modelRenderKit.leftWeapon!=null)
            {
                GameObject leftWeapon = Object.Instantiate(modelRenderKit.leftWeapon);
                leftWeapon.transform.SetParent(meshLeftWeapon.transform);
                leftWeapon.transform.localPosition = Vector3.zero;
                leftWeapon.transform.localEulerAngles = Vector3.zero;
                leftWeapon.transform.localScale = Vector3.one;
            }

            if(modelRenderKit.rightWeapon!=null)
            {
                GameObject rightWeapon = Object.Instantiate(modelRenderKit.rightWeapon);
                rightWeapon.transform.SetParent(meshRightWeapon.transform);
                rightWeapon.transform.localPosition = Vector3.zero;
                rightWeapon.transform.localEulerAngles = Vector3.zero;
                rightWeapon.transform.localScale = Vector3.one;
            }

        }
#endregion MeshAnimation

    }
}

